﻿<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style type="text/css">
        body,ul,li img{
            margin: 0;
            padding: 0;
        }
        body{
            background: #eeeeee;
            color: #999;
            overflow: hidden;
        }
        li{
            list-style: none;
        }
        .progress{
            width: 100%;
            height: 4px;
            background: #fff;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 10;
        }
        .progress1{
            width: 0%;
            height: 4px;
            position: absolute;
            left: 0;
            top: 0;
        }
        .btnarea{
            width: 100%;
            height: 300px;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 7;
            transition: 1s;
        }
        .line1{
            width: 2px;
            height: 160px;
            background: #FFFFFF;
            position: absolute;
            top: 0;
            left: 30%;
        }
        .arc1{
            width: 80px;
            height: 80px;
            border-radius: 50%;
            background: #FFF;
            position: absolute;
            top: 160px;
            left: -39px;
            line-height: 80px;
            z-index: 9;
            cursor: pointer;
            text-align: center;
            -webkit-transform: translateY(-50px);
        }
        .line2 {
            width: 2px;
            height: 240px;
            background: #FFF;
            position: absolute;
            top: 0px;
            left: 40%;
        }
        .arc2 {
            width: 110px;
            height: 110px;
            border-radius: 50%;
            background: #FFF;
            position: absolute;
            top: 240px;
            left: -54px;
            line-height: 110px;
            z-index: 9;
            cursor: pointer;
            text-align: center;
            -webkit-transform: translateY(-50px);
        }
        .line3 {
            width: 2px;
            height: 100px;
            background: #FFF;
            position: absolute;
            top: 0px;
            left: 50%;
        }
        .arc3 {
            width: 60px;
            height: 60px;
            border-radius: 50%;
            background: #FFF;
            position: absolute;
            top: 125px;
            left: -29px;
            line-height: 60px;
            z-index: 9;
            cursor: pointer;
            text-align: center;
            -webkit-transform: translateY(-50px);
        }
        .line4 {
            width: 2px;
            height: 200px;
            background: #FFF;
            position: absolute;
            top: 0px;
            left: 60%;
        }
        .arc4 {
            width: 80px;
            height: 80px;
            border-radius: 50%;
            background: #FFF;
            position: absolute;
            top: 200px;
            left: -39px;
            line-height: 80px;
            z-index: 9;
            cursor: pointer;
            text-align: center;
            -webkit-transform: translateY(-50px);
        }
        .line5 {
            width: 2px;
            height: 140px;
            background: #FFF;
            position: absolute;
            top: 0px;
            left: 70%;
        }
        .arc5 {
            width: 100px;
            height: 100px;
            border-radius: 50%;
            background: #FFF;
            position: absolute;
            top: 140px;
            left: -50px;
            line-height: 100px;
            z-index: 9;
            cursor: pointer;
            text-align: center;
            -webkit-transform: translateY(-50px);
        }
        .div1{
            width: 100%;
            position: absolute;
            left: 0;
            bottom: -10px;
            height: 1000px;
            overflow: hidden;
        }
        .oUl{
            position: absolute;
            left: 0;
            bottom: 0;
            transition: transform .4s cubic-bezier(.445,.05,.55,.95);
        }
        .oUl li{
            float: left;
            width: 13.8%;
            position: relative;
            transition: transform .4s cubic-bezier(.445,.05,.55,.95);
        }
        .oUl img{
            width: 100%;
            max-width: 100%;
            height: auto;
            position: relative;
            will-change: transform;
            cursor: pointer;
            background-size: contain;
            background-repeat: no-repeat;
            -webkit-transition: transform .2s cubic-bezier(0,.68,.86,.98);
            -transition: transform .2s cubic-bezier(0,.68,.86,.98);
        }
        .oUl li:nth-child(1) img {
            -webkit-transform: translate3d( 0px,63%,0px);
            background-image: url(./img/1-1.png);
        }
        .oUl li:nth-child(2) img {
            -webkit-transform: translate3d( 0px,47%,0px);
            background-image: url(./img/2-2.png);
        }
        .oUl li:nth-child(3) img {
            -webkit-transform: translate3d( 0px,67%,0px);
            background-image: url(./img/3-3.png);
        }
        .oUl li:nth-child(4) img {
            -webkit-transform: translate3d( 0px,47%,0px);
            background-image: url(./img/4-4.png);
        }
        .oUl li:nth-child(5) img {
            -webkit-transform: translate3d( 0px,27%,0px);
            background-image: url(./img/5-5.png);
        }
        .oUl li:nth-child(6) img {
            -webkit-transform: translate3d( 0px,47%,0px);
            background-image: url(./img/6-6.png);
        }
        .oUl li:nth-child(7) img {
            -webkit-transform: translate3d( 0px,61%,0px);
            background-image: url(./img/7-7.png);
        }
        .active{ box-shadow:1px 1px 5px 0px rgba(0,0,0,0.2); color:#FFF;}

        .oUl li.prev{
            transform: translate3d(-13%,0,0);
        }
        .oUl li.next{
            transform: translate3d(13%,0,0);
        }
        #large ul li:nth-child(n) img{
            transform: translate3d(0,25%,0) !important;
        }
        #large ul li.large img{
            transform: translate3d(0,15%,0) !important;
        }
    </style>
</head>
<body>
    <div class="progress">
        <div class="progress1"></div>
    </div>
    <div class="btnarea">
        <div class="line1">
            <div class="arc1 btn">轻柔</div>
        </div>
        <div class="line2">
            <div class="arc2 btn">节奏</div>
        </div>
        <div class="line3">
            <div class="arc3 btn">DJ</div>
        </div>
        <div class="line4">
            <div class="arc4 btn">纯音乐</div>
        </div>
        <div class="line5">
            <div class="arc5 btn">停止</div>
        </div>
    </div>
    <div class="div1">
        <ul class="oUl">
            <li><img src="./img/1-1.png" alt=""/></li>
            <li><img src="./img/2-2.png" alt=""/></li>
            <li><img src="./img/3-3.png" alt=""/></li>
            <li><img src="./img/4-4.png" alt=""/></li>
            <li><img src="./img/5-5.png" alt=""/></li>
            <li><img src="./img/6-6.png" alt=""/></li>
            <li><img src="./img/7-7.png" alt=""/></li>
        </ul>
    </div>
</body>
</html>
<script type="text/javascript">

    //获取class
    function getClass(oParent,sClass)
    {
        var aEle=oParent.getElementsByTagName('*');	//*抓取所有元素
        var result=[];
        for(var i=0;i<aEle.length;i++){
            var arr=aEle[i].className.split(' ');
            for(var j=0;j<arr.length;j++){
                if(arr[j]==sClass){
                    result.push(aEle[i]);
                    break;
                }
            }
        }
        return result;
    }

    //添加类
    function addClass(obj,sClass)
    {
        var aClass=obj.className.split('');
        if(!aClass[0])
        {
            obj.className=sClass;
            return
        }
        for(var i=0;i<aClass.length;i++)
        {
            if(aClass[i]==sClass)
            {
                return;
            }
        }
        obj.className+=' '+sClass;
    }

    //移除类
    function removeClass(obj,sClass){

        var aClass = obj.className.split(' ');
        if(!aClass[0])return;
        for(var i=0; i<aClass.length; i++){
            if(aClass[i]==sClass){
                aClass.splice(i,1);
                obj.className = aClass.join(' ');
                return;
            }
        }
    }

    //找到某个元素距离屏幕最左边的距离
    function offsetL( obj ){
        var left = 0;
        while( obj ){
            left += obj.offsetLeft;
            obj = obj.offsetParent;
        }
        return left;
    }

    //产生随机数
    function rnd(n,m){
        return parseInt(Math.random()*(m-n)+n);
    }

    window.onload=function(){
        document.body.style.height=document.documentElement.clientHeight+'px';
        var player=new Player();
        player.ini();
    };

    var oBody=document.getElementsByTagName('body')[0];
    var progress=getClass(oBody,'progress1')[0];//进度条
    var btn=getClass(oBody,'btnarea')[0];//按钮列表
    var phones=getClass(oBody,'oUl')[0];//phone 列表
    var arrImg=phones.getElementsByTagName('img');
    var pLi=phones.getElementsByTagName('li');

    var Player=function(){
        this.audio=null;//audio对象
        this.actx=null;//actx对象
        this.colors=null;//颜色
        this.analyser=null;//分析器
        this.source=null;//音频 src
        this.audioBufferSourceNode=null;//源节点
        this.acBtn=null;//当前激活按钮
        this.acColor=null;//当前激活按钮颜色
        this.animationId=null;//随音乐逐帧动画
    };

    Player.prototype={
        ini: function () {
            this._prepare();
            this._addEvent();
        },

        _prepare: function () {
            this.source=[
                'img/mo.mp3',
                'img/Rihanna - Only Girl (In The World).mp3',
                'img/Remix.mp3',
                'img/Neptune Illusion Dennis Kuo .mp3'
            ];
            this.colors=[
                '#ffd96d',
                '#8cf6f3',
                '#92aef0',
                '#b897e4',
                '#ff5f5b',
                '#ffb66e'
            ];

            //兼容性处理
            window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
            window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame;
            window.AudioContext = window.AudioContext || window.webkitAudioContext || window.mozAudioContext || window.msAudioContext;
            try {
                this.actx = new window.AudioContext();
            } catch (e) {
                console.log(e+'浏览器不支持AudioContext');
            }

            //添加手机索引值index
            for(var i=0;i<pLi.length;i++)
            {
                pLi[i].style.width=(1/pLi.length)*100+'%';
                arrImg[i].index=i;
            }
        },
        
        _addEvent: function () {
            this._phones();
            this._audio();
        },

		//底部手机点击和鼠标移动事件
        _phones: function () {
            var that=this;
            var time1=null;//
            var timer=null;
            var cX=null;//鼠标X坐标
            flag=false;//false为未激活
            var maxDis=phones.offsetWidth*5/7;
            phones.onmousemove= mMove;
            phones.onmouseleave= mLeave;

            //mousemove事件
            function mMove(e) {
                var oEvt=e||event;
                cX= oEvt.clientX;
                time1=new Date().valueOf();//获取当前时间

                //清除上一个帧动画，进行新的帧动画
                cancelAnimationFrame(timer);//清除帧动画
                timer=requestAnimationFrame(move);//执行帧动画
            }

            //mouseout事件
            function mLeave() {
                cancelAnimationFrame(timer);
                that._reImg();//手机回归原位
            }

            //利用 requestAnimationFrame 实现缓冲动画
            function move(){
                var time2=new Date().valueOf();//获取时间
                for(var i=0;i<arrImg.length;i++)
                {
                    var l=offsetL(arrImg[i])+arrImg[i].offsetWidth/2;//图片中心距离屏幕左侧距离
                    var dis=Math.abs(cX-l);//鼠标距离img中心距离（x）
                    if(dis>maxDis)
                    {dis=maxDis;}
                    var s=(dis/maxDis)*60; 
                    var top=Math.abs(arrImg[i].getBoundingClientRect().top-phones.getBoundingClientRect().top);//获取img到ul顶部距离
                    var n=top/arrImg[i].offsetHeight*100;  //当前相对于顶部translateY 的百分比*100
                    var o=(s-n)/5;//位移量
                    n+=o;
                    arrImg[i].style.cssText = "-webkit-transform:translate3d(0," + n + "%,0);transform:translate3d(0," + n +"%,0);-webkit-transition:none;transition:none;";
                }
                if(time2-time1<1000)//鼠标放上的1s内执行执行帧动画，超出则不继续执行，超出执行音频动画或不执行动画
                {
                    timer=requestAnimationFrame(move);//继续执行帧动画实现缓冲效果
                }
            }



            phones.onclick= function (ev) {
                var oEvt=ev||event;
                cancelAnimationFrame(timer);
                if(!flag){
                    var target=oEvt.target;
                    if(target.nodeName==="LI"){
                        target=oEvt.target.children[0];
                    }
                    btn.style.webkitTransform='translateY(-350px)';
                    var left=offsetL(target)+target.offsetWidth/2;//target中心距离屏幕左侧距离
                    var disX=(document.documentElement.clientWidth/2-left)*3;
                    for(var i=0;i<arrImg.length;i++){
                        arrImg[i].style.webkitTransition = "-webkit-transform .4s cubic-bezier(0.445, 0.05, 0.55, 0.95)";
                        arrImg[i].style.transition = "transform .4s cubic-bezier(0.445, 0.05, 0.55, 0.95)";
                    }

                    document.body.id="large";
                    phones.style.cssText="-webkit-transform : translate3d(" + disX + "px, 0, 0) scale(3);transform : translate3d(" + disX + "px, 0, 0) scale(3)";
                    for(var j=0;j<arrImg.length;j++){
                        if(j<target.index)
                        {
                            arrImg[j].parentNode.className="prev";
                        }else if(i>target.index){
                            arrImg[j].parentNode.className="next";
                        }
                    }

                    target.parentNode.className="large";
                    phones.onmousemove=phones.onmouseleave=null;

                    flag=true;
                }
                else {
                    phones.removeAttribute("style");
                    btn.style.webkitTransform = 'translateY(0px)';
                    for(var i=0;i<arrImg.length;i++)
                    {
                        arrImg[i].parentNode.className="";
                    }

                    document.body.id="";
                    setTimeout(function(){
                        phones.onmousemove=mMove;
                        phones.onmouseleave=mLeave;
                        flag=false;
                    },300);

                }
            }
        },

        _audio: function () {
            var that=this;

            that.audio=new Audio;
            var bts=getClass(btn,'btn');
            //console.log(bts);
            for(var i=0;i<bts.length-1;i++)
            {
                bts[i].index=i;
                bts[i].onclick= function () {
                    iniAudio();
                    that.acColor=that.colors[rnd(0,6)];
                    this.style.background=that.acColor;
                    this.parentNode.style.background=that.acColor;
                    progress.style.background=that.acColor;
                    addClass(this,'active');
                    that.acBtn=this;
                  //  that.audio.crossOrigin = 'anonymous';//无关代码
                    that.audio.src=that.source[this.index];//设置src会自动加载音频
                    //监听事件audio的加载情况，是否可以播放
                    that.audio.addEventListener("canplay", function (e) {
                        that.analyser=that.audioBufferSourceNode=null;
                        that._connect();
                    },false);
                }
            }

            //停止按钮
            bts[bts.length-1].onclick= function () {
                cancelAnimationFrame(that.animationId);
                iniAudio();
                that._reImg();
            };

            function iniAudio(){
                that.audio.pause();
                that.audio=null;
                that.audio=new Audio();

                for(var i=0;i<bts.length-1;i++){
                    removeClass(bts[i],'active');
                    bts[i].removeAttribute('style');
                    bts[i].parentNode.removeAttribute('style');
                }
            }
        },

        _connect: function () {
            var that=this;

            that.audioBufferSourceNode=that.actx.createMediaElementSource(that.audio);//设置源节点的数据源 ，数据源来自audio对象
          //  that.audioBufferSourceNode.crossOrigin='anonymous';//无关代码
            that.analyser=that.actx.createAnalyser();//创建解码器

            that.audioBufferSourceNode.connect(that.analyser);//源节点连接解码器

            //以下两种方法都可以
           // that.audioBufferSourceNode.connect(that.actx.destination);//源节点连接扬声器  // 扬声器<---源--->解码器
            that.analyser.connect(that.actx.destination);//解码器链接扬声器  //源--->解码器--->扬声器


            that.audio.play();
            that._jump();
        },

        _jump: function () {
            var that=this;
            function animate1(){
                //analyser会在源抛出信息时不停收集信息
                //得到的音频是一个二进制的，需要，解析数据
                var array=new Uint8Array(that.analyser.frequencyBinCount);//长度1024
                //获取数据，填充数组
                that.analyser.getByteFrequencyData(array);
                var step=parseInt(array.length/10);//设置从数组中获取音频数据的间隔
                var j=0;
                for(var i=0;i<arrImg.length;i++)
                {
                    var num=70*(1-array[j]/256);
                    j+=step;
                    //设置手机位移Y
                    arrImg[i].style.cssText = "-webkit-transform:(0," + num + "%,0);transform:translate3d(0," + num +"%,0)";
                }
                var s=(160*(array[100]/256)+100)/100*(document.body.offsetHeight/phones.offsetWidth);
                //绘制按钮的跳动
                that.acBtn.style.cssText+="-webkit-transform: translateY(-50px) scale("+ s +","+ s +");transform: translateY(-50px) scale("+ s +","+ s +")";
                //绘制进度条
                progress.style.width=that.audio.currentTime/that.audio.duration*100+'%';
                //继续执行帧动画
                that.animationId=requestAnimationFrame(animate1);
            }
            that.animationId=requestAnimationFrame(animate1);
        },

        //手机回归原位
        _reImg:function(){
            for(var i=0;i<arrImg.length;i++)
            {
                arrImg[i].removeAttribute('style');
            }
        }

    };
</script>